home *** CD-ROM | disk | FTP | other *** search
-
- Here are some changes I made to objdump which allow it to dump section
- contents as raw data. This is usefull if you need to make an image
- of an executable to load into memory with out the help of the
- operating systems. We use this to make boot images of the Linux
- kernel under ELF as well as for dynamic loading of kernel modules.
- Another case when they would be useful, is for making ROM Images.
-
- I've also enclosed source for another program called encaps which
- takes raw data and makes it a .o file. It's useful for adding
- resources are other data to a program without recompiling. We use
- it to include 16 bit minix assembly in the Linux kernel.
-
- Ross Biro biro@yggdrasil.com
-
- ------ CUT HERE ------
- ---
- *** objdump.c.~1~ Wed Sep 28 13:06:43 1994
- --- objdump.c Mon Nov 14 06:57:47 1994
- ***************
- *** 15,24 ****
- --- 15,28 ----
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- + /* Added -k, -o, -q options for use with the Linux kernel
- + * 11/94 Ross Biro biro@yggdrasil.com
- + */
- +
- #include "bfd.h"
- #include "sysdep.h"
- #include "getopt.h"
- #include "bucomm.h"
- #include <stdio.h>
- ***************
- *** 38,47 ****
- --- 42,54 ----
-
- extern char *program_version;
-
- int show_version = 0; /* show the version number */
- int dump_section_contents; /* -s */
- + int dump_section_raw=0; /* -k */
- + int raw_offset=0; /* -o */
- + int quiet=0; /* -q */
- int dump_section_headers; /* -h */
- boolean dump_file_header; /* -f */
- int dump_symtab; /* -t */
- int dump_dynamic_symtab; /* -T */
- int dump_reloc_info; /* -r */
- ***************
- *** 112,128 ****
- usage (stream, status)
- FILE *stream;
- int status;
- {
- fprintf (stream, "\
- ! Usage: %s [-ahifdDrRtTxsl] [-b bfdname] [-m machine] [-j section-name]\n\
- [--archive-headers] [--target=bfdname] [--disassemble]\n\
- [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
- [--info] [--section=section-name] [--line-numbers]\n\
- [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
- [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
- ! [--version] [--help] objfile...\n\
- at least one option besides -l (--line-numbers) must be given\n",
- program_name);
- exit (status);
- }
-
- --- 119,135 ----
- usage (stream, status)
- FILE *stream;
- int status;
- {
- fprintf (stream, "\
- ! Usage: %s [-ahifdDkoqrRtTxsl] [-b bfdname] [-m machine] [-j section-name]\n\
- [--archive-headers] [--target=bfdname] [--disassemble]\n\
- [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
- [--info] [--section=section-name] [--line-numbers]\n\
- [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
- [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
- ! [--version] [--help] [--offset=offset] [--raw] [--quiet] objfile...\n\
- at least one option besides -l (--line-numbers) must be given\n",
- program_name);
- exit (status);
- }
-
- ***************
- *** 139,148 ****
- --- 146,158 ----
- {"full-contents", no_argument, NULL, 's'},
- {"headers", no_argument, NULL, 'h'},
- {"help", no_argument, NULL, 'H'},
- {"info", no_argument, NULL, 'i'},
- {"line-numbers", no_argument, NULL, 'l'},
- + {"offset", required_argument, NULL, 'o'},
- + {"quiet", no_argument, NULL, 'q'},
- + {"raw", no_argument, NULL, 'k'/* k for kernel */},
- {"reloc", no_argument, NULL, 'r'},
- {"section", required_argument, NULL, 'j'},
- {"section-headers", no_argument, NULL, 'h'},
- {"stabs", no_argument, &dump_stab_section_info, 1},
- {"syms", no_argument, NULL, 't'},
- ***************
- *** 980,992 ****
- list_matching_formats (matching);
- free (matching);
- }
- return;
- }
- !
- ! printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
- ! abfd->xvec->name);
- if (dump_ar_hdrs)
- print_arelt_descr (stdout, abfd, true);
- if (dump_file_header)
- dump_bfd_header (abfd);
- putchar ('\n');
- --- 990,1002 ----
- list_matching_formats (matching);
- free (matching);
- }
- return;
- }
- ! if (!quiet)
- ! printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
- ! abfd->xvec->name);
- if (dump_ar_hdrs)
- print_arelt_descr (stdout, abfd, true);
- if (dump_file_header)
- dump_bfd_header (abfd);
- putchar ('\n');
- ***************
- *** 1031,1042 ****
- }
-
- if (bfd_check_format (file, bfd_archive) == true)
- {
- bfd *last_arfile = NULL;
- !
- ! printf ("In archive %s:\n", bfd_get_filename (file));
- for (;;)
- {
- bfd_set_error (bfd_error_no_error);
-
- arfile = bfd_openr_next_archived_file (file, arfile);
- --- 1041,1052 ----
- }
-
- if (bfd_check_format (file, bfd_archive) == true)
- {
- bfd *last_arfile = NULL;
- ! if (!quiet)
- ! printf ("In archive %s:\n", bfd_get_filename (file));
- for (;;)
- {
- bfd_set_error (bfd_error_no_error);
-
- arfile = bfd_openr_next_archived_file (file, arfile);
- ***************
- *** 1073,1082 ****
- --- 1083,1093 ----
- {
- asection *section;
- bfd_byte *data = 0;
- bfd_size_type datasize = 0;
- bfd_size_type i;
- + int err;
-
- for (section = abfd->sections; section != NULL; section =
- section->next)
- {
- int onaline = 16;
- ***************
- *** 1084,1128 ****
- if (only == (char *) NULL ||
- strcmp (only, section->name) == 0)
- {
- if (section->flags & SEC_HAS_CONTENTS)
- {
- ! printf ("Contents of section %s:\n", section->name);
-
- if (bfd_section_size (abfd, section) == 0)
- continue;
- data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
- datasize = bfd_section_size (abfd, section);
-
-
- bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
-
- ! for (i = 0; i < bfd_section_size (abfd, section); i += onaline)
- ! {
- ! bfd_size_type j;
-
- ! printf (" %04lx ", (unsigned long int) (i + section->vma));
- ! for (j = i; j < i + onaline; j++)
- ! {
- ! if (j < bfd_section_size (abfd, section))
- ! printf ("%02x", (unsigned) (data[j]));
- ! else
- ! printf (" ");
- ! if ((j & 3) == 3)
- ! printf (" ");
- ! }
-
- ! printf (" ");
- ! for (j = i; j < i + onaline; j++)
- ! {
- ! if (j >= bfd_section_size (abfd, section))
- ! printf (" ");
- ! else
- ! printf ("%c", isprint (data[j]) ? data[j] : '.');
- ! }
- ! putchar ('\n');
- }
- free (data);
- }
- }
- }
- }
- --- 1095,1155 ----
- if (only == (char *) NULL ||
- strcmp (only, section->name) == 0)
- {
- if (section->flags & SEC_HAS_CONTENTS)
- {
- ! if (!quiet)
- ! printf ("Contents of section %s:\n", section->name);
-
- if (bfd_section_size (abfd, section) == 0)
- continue;
- data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
- datasize = bfd_section_size (abfd, section);
-
-
- bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
-
- ! if (dump_section_raw) {
- ! if (section->vma < raw_offset) continue;
-
- ! if (fseek (stdout, section->vma-raw_offset, SEEK_SET)) {
- ! perror ("fseek");
- ! }
-
- ! err =fwrite (data,1, bfd_section_size (abfd, section), stdout);
- ! if (err != bfd_section_size (abfd, section)) {
- ! perror ("fwrite");
- ! return;
- }
- +
- + } else {
- + for (i = 0; i < bfd_section_size (abfd, section); i += onaline)
- + {
- + bfd_size_type j;
- +
- + printf (" %08lx ", (unsigned long int) (i + section->vma));
- + for (j = i; j < i + onaline; j++)
- + {
- + if (j < bfd_section_size (abfd, section))
- + printf ("%02x", (unsigned) (data[j]));
- + else
- + printf (" ");
- + if ((j & 3) == 3)
- + printf (" ");
- + }
- +
- + printf (" ");
- + for (j = i; j < i + onaline; j++)
- + {
- + if (j >= bfd_section_size (abfd, section))
- + printf (" ");
- + else
- + printf ("%c", isprint (data[j]) ? data[j] : '.');
- + }
- + putchar ('\n');
- + }
- + }
- free (data);
- }
- }
- }
- }
- ***************
- *** 1504,1514 ****
- program_name = *argv;
- xmalloc_set_program_name (program_name);
-
- bfd_init ();
-
- ! while ((c = getopt_long (argc, argv, "ib:m:VdDlfahrRtTxsj:", long_options,
- (int *) 0))
- != EOF)
- {
- seenflag = true;
- switch (c)
- --- 1531,1541 ----
- program_name = *argv;
- xmalloc_set_program_name (program_name);
-
- bfd_init ();
-
- ! while ((c = getopt_long (argc, argv, "kqo:ib:m:VdDlfahrRtTxsj:", long_options,
- (int *) 0))
- != EOF)
- {
- seenflag = true;
- switch (c)
- ***************
- *** 1549,1558 ****
- --- 1576,1595 ----
- case 'd':
- disassemble = true;
- break;
- case 'D':
- disassemble = disassemble_all = true;
- + break;
- + case 'q':
- + quiet = 1;
- + break;
- + case 'k':
- + dump_section_raw = 1;
- + dump_section_contents = 1;
- + break;
- + case 'o':
- + raw_offset = atoi (optarg);
- break;
- case 's':
- dump_section_contents = 1;
- break;
- case 'r':
- ------ CUT HERE ------
- *** objdump.1.~1~ Thu Sep 15 21:59:29 1994
- --- objdump.1 Mon Nov 14 06:50:42 1994
- ***************
- *** 29,45 ****
- --- 29,52 ----
- .RB "[\|" \-i | \-\-info "\|]"
- .RB "[\|" "\-j\ "\c
- .I section\c
- .RB " | " "\-\-section="\c
- .I section\c
- + .RB "[\|" \-k | \-\-raw "\|]"
- \&\|]
- .RB "[\|" \-l | \-\-line\-numbers "\|]"
- .RB "[\|" "\-m\ "\c
- .I machine\c
- .RB " | " "\-\-architecture="\c
- .I machine\c
- \&\|]
- + .RB "[\|" "\-o\ "\c
- + .I offset\c
- + .RB " | " "\-\-offset="\c
- + .I offset\c
- + \&\|]
- + .RB "[\|" \-q | \-\-quiet "\|]"
- .RB "[\|" \-r | \-\-reloc "\|]"
- .RB "[\|" \-R | \-\-dynamic\-reloc "\|]"
- .RB "[\|" \-s | \-\-full\-contents "\|]"
- .RB "[\|" \-\-stabs "\|]"
- .RB "[\|" \-t | \-\-syms "\|]"
- ***************
- *** 181,190 ****
- --- 188,206 ----
- Display information only for section \c
- .I name\c
- \&
-
- .TP
- + .B \-k
- + .TP
- + .B \-\-raw
- + Dump all the loadable section contents as raw data on stdout.
- + Useful for making
- + boot images or turning an executable into raw data. Some architectures
- + (such as elf) require that stdout be seekable for this to work.
- +
- + .TP
- .B \-l
- .TP
- .B \-\-line\-numbers
- Label the display (using debugging information) with the filename
- and source line numbers corresponding to the object code shown.
- ***************
- *** 202,211 ****
- --- 218,240 ----
- .I machine\c
- \&. You can list available architectures using the `\|\c
- .B \-i\c
- \|'
- option.
- +
- + .TP
- + .BI "\-o " "offset"\c
- + .TP
- + .BI "\-\-offset=" "offset"\c
- + \&
- + The offset to make byte 0 of a raw dump.
- +
- + .TP
- + .B \-q
- + .TP
- + .B \-\-quiet
- + Supress most informational messages, useful with \fB\-k\fP.
-
- .TP
- .B \-r
- .TP
- .B \-\-reloc
- ------ CUT HERE ------
- /* encaps.c */
- /* Copyright (C) 1994 Yggdrasil Computing, Incorporated
- 4880 Stevens Creek Blvd. Suite 205
- San Jose, CA 95129-1034
- USA
- Tel (408) 261-6630
- Fax (408) 261-6631
-
- Encaps is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Written by Ross Biro Nov 94 */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <malloc.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <unistd.h>
- #include <getopt.h>
-
- #include "ansidecl.h"
- #include <bfd.h>
-
- #define obstack_chunk_alloc malloc
- #define obstack_chunk_free free
-
- #define DEF_SEC_FLAGS SEC_ALLOC|SEC_LOAD|SEC_RELOC|SEC_HAS_CONTENTS
-
- /* This is the routine that does most of the work. */
- /* file is the name of the output file
- target is the target type "a.out-i386-linux" for example
- secflags is ored with DEFAULT_SEC_FLAGS and then applied.
- It is used to say if the section is data or code. (Normally
- SEC_DATA.
- format is the file format to write (Normally bfd_object)
- symname is the name to give the symbol.
- secname is the name of the section (.data is good)
- fd is the file descriptor for the data to be put in the file.
- */
-
- int
- encapsulate (const char *file, const char *target, unsigned long secflags,
- bfd_format format, const char *symname, char *lengthname,
- const char *secname,
- int fd) {
- bfd *abfd;
- asection *sec;
- size_t length;
- unsigned char *ptr;
- struct stat st;
- asymbol *syms[3];
- asymbol *new;
-
- bfd_init();
- bfd_check_init();
-
- abfd = bfd_openw(file, target);
-
- if (abfd == NULL) {
- fprintf (stderr, "Error Openning %s file %s: %s\n",target, file,
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- #ifdef __i386__
- /* This wonderful poorly document call is absolutely necessary. */
- /* The linker deals with this in a much better way. Perhaps the
- code should be borowed. */
- bfd_default_set_arch_mach (abfd, bfd_arch_i386, 0);
- #endif
-
- if (!bfd_set_format (abfd, format)) {
- fprintf (stderr, "Error settting format: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- sec = bfd_make_section (abfd, secname);
-
- if (sec == NULL) {
- fprintf (stderr, "Error Making Section: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- if (!bfd_set_section_flags(abfd, sec, DEF_SEC_FLAGS | secflags)) {
- fprintf (stderr, "Error settting section flags %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- /* We are ready for the data. */
- if (fstat (fd, &st)) {
- fprintf (stderr, "Error Stating Data File: %s\n",
- strerror (errno));
- return (errno);
- }
-
- length = st.st_size;
-
- /* create a new symbol */
-
- new = bfd_make_empty_symbol (abfd);
- if ((unsigned long)new < 4096) {
- fprintf (stderr, "Error allocating symbol: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- new->name = symname;
- new->section = sec;
- new->flags = BSF_EXPORT;
- new->value =sizeof (char *);
- syms[0]=new;
-
-
- new = bfd_make_empty_symbol (abfd);
- if ((unsigned long)new < 4096) {
- fprintf (stderr, "Error allocating symbol: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- new->name = lengthname;
- new->section = sec;
- new->flags = BSF_EXPORT;
- new->value =0;
- syms[1]=new;
-
- syms[2]=NULL;
-
- if (!bfd_set_symtab (abfd, syms, 2)) {
- fprintf (stderr, "Error setting symbol table: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- /* mmap would be good here, but if I do it, I can't easily
- add the length info. Oh well
- ptr = mmap (0, length, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
-
- if (ptr == NULL) {
- fprintf (stderr, "Error mmapping Data File: %s\n",
- strerror (errno));
- return (errno);
- }
- */
- ptr = malloc (length + sizeof (char *));
-
- if (ptr == NULL) {
- fprintf (stderr, "Error allocating memory for data file: %s\n",
- strerror (errno));
- return (errno);
- }
-
- /* this is technically a bug. For example a ctrl-z bg may break this. */
- if (read (fd, ptr+sizeof (char *), length) != length) {
- fprintf (stderr, "Error reading file: %s\n",
- strerror (errno));
- return (errno);
- }
- *(unsigned long*)ptr = length;
-
- if (! bfd_set_section_size (abfd, sec, length+sizeof(char *))) {
- fprintf (stderr, "Error settting section size %s:\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- if (! bfd_set_section_contents (abfd, sec, ptr, 0, length+sizeof (char *))) {
- fprintf (stderr, "Error settting section contents: %s\n",
- bfd_errmsg (bfd_get_error()));
- return (bfd_get_error()<<16| errno);
- }
-
- /* write out everything. */
- bfd_close (abfd);
- return (0);
- }
-
- void
- usage (char *name) {
- fprintf (stderr, "usage %s: [-f format] [-n secname] [-t target] [-s secflags] output-file input-file symbol-name length-name\n", name);
- fpritnf (stderr," --format format file format to write.\n");
- fpritnf (stderr," --section_name name of the section (normally .data)\n");
- fpritnf (stderr," --target target target name (a.out-linux-i386 elf32-i386)\n");
- fpritnf (stderr," --sectionflags flags flags to put in section header\n");
- exit (1);
-
- }
-
-
- int main (int argc, char *argv[]) {
- int c;
- char *outfile=NULL;
- char *infile=NULL;
- char *target="a.out-i386-linux";
- int secflags = SEC_DATA;
- bfd_format format = bfd_object;
- char *symname = NULL;
- char *lengthname = NULL;
- char *secname = ".data";
- int fd = -1;
-
- int option_index;
- static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"format", 1, 0, 'f'},
- {"section-name", 1, 0, 'n'},
- {"target", 1, 0, 't'},
- {"sectionflags", 1, 0, 's'},
- };
-
- while ((c = getopt_long (argc, argv, "hf:t:n:s:",
- long_options, &option_index)) > 0) {
- switch (c) {
- case 'h':
- case '?':
- default:
- usage(argv[0]);
-
- case 'f':
- format = atoi(optarg);
- break;
-
- case 'n':
- secname = optarg;
- break;
-
- case 't':
- target = optarg;
- break;
-
- case 's':
- secflags=atoi (optarg);
- break;
-
- }
- }
- if (argc - optind != 4) usage(argv[0]);
-
- outfile = argv[optind];
- infile= argv[optind+1];
- symname = argv[optind+2];
- lengthname = argv[optind+3];
- fd = open (infile, O_RDONLY);
- if (fd < 0) {
- fprintf (stderr, "error opening infile %s: %s\n", infile,
- strerror(errno));
- exit (1);
- }
-
- if (encapsulate (outfile, target, secflags, format, symname, lengthname,
- secname, fd))
- return (1);
-
- return (0);
- }
-
-
-